package com.zu.commu.local.threads;

import com.zu.commu.context.ServerContext;
import com.zu.commu.local.LocalServer;
import com.zu.commu.local.process.LocalProcess;
import org.apache.log4j.Logger;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

public class LocalReadThread extends Thread {
	Logger log = Logger.getLogger(LocalReadThread.class);
	private boolean canRead;
	private SocketChannel channel;
	private int num;

	public LocalReadThread(int num) {
		this.canRead = false;
		this.num = num;
	}

	public void setReadSocketChannel(SocketChannel channel) {
		synchronized (this) {
			this.channel = channel;
			this.canRead = true;
			notify();
		}
	}

	public void run() {
		while (true) {
			synchronized (this) {
				while (!this.canRead) {
					try {
						//释放锁等待任务
						wait();
						log.debug("LocalThreads:" + this.getName()	+ "New Work，EndWait。。。");
					} catch (Exception e) {
						log.error("线程 " + this.num + " 等待可读信号时发生等待异常", e);
					}
				}
				ByteBuffer buffer = ByteBuffer
						.allocate(ServerContext.bufferSizeForReadLocalSocket);
				boolean isException = false;
				boolean isConnected = true;

				try {
					if (this.channel.read(buffer) == -1) {
						isConnected = false;
					} else
						buffer.flip();
				} catch (Exception e) {
					isException = true;
					log.error("线程 " + this.num + "从LocalSocketChannel读取数据发生异常，"
							+ e.getMessage());
				} finally {

					try {
						if ((!isException) && (isConnected)) {
							byte[] bs = buffer.array();
							new LocalProcess().processData(this.channel, bs);
							buffer = null;
						}
					} catch (Exception e) {
						buffer = null;
					} finally {
						try {
							SelectionKey seleKey = this.channel
									.keyFor(LocalServer.getSelector());
							if (seleKey != null) {
								seleKey.cancel();
							}
							this.channel.finishConnect();
							this.channel.socket().close();
							this.channel.close();
						} catch (Exception eee) {
							this.channel = null;
						} finally {
							this.canRead = false;

							LocalReadThreadManager.instance().freeThread(
									this.num, this);
						}
					}
				}
			}

		}
	}

	public void destroy() {
		this.channel = null;
	}
}